package evaluation;

import java.util.ArrayList;
import java.util.LinkedList;

import utils.Constante;

public class Evaluateur {
    private static boolean isWhitePlayer;
    static char[] colonne = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'};
    
    //Value for the pousse and pousseur. 
    static final int valuePousse = 2;
    static final int valuePousseur = 4;
    
    //Value for winning or losing board
    static final int winningBoard = 100;
    static final int losingBoard = -100;
    
    //Value from the distance of a pion from the finish line
    //starting from the middle.
    static final double positionValue = 10;
        
    public static void setWhitePlayer(boolean type) {
        isWhitePlayer = type;
    }
    
    public static boolean isWhitePlayer() {
        return isWhitePlayer;
    }
    
    public static void showBoard(int [][] board){
        System.out.println("New Board ! Evaluated");
        System.out.println("");
        for (int i=0;i<8;i++){
            for(int j=0;j<8;j++){
                System.out.print(board[i][j] + " ");                
            }
            System.out.println("");
        }
        System.out.println("");
    }
    
    
    public static ArrayList<Integer> countNumberPiece(int[][] board){
        ArrayList<Integer> nbPiece = new ArrayList<Integer>();
        nbPiece.add(0,0);
        nbPiece.add(1,0);
        nbPiece.add(2,0);
        nbPiece.add(3,0);
        nbPiece.add(4,0);
        
        for (int i=0;i<8;i++){
            for(int j=0;j<8;j++){
                if(board[i][j] != 0) {
                    int nbAct = nbPiece.get(board[i][j]);
                    nbAct ++;
                    nbPiece.set(board[i][j], nbAct);
                }
            }
        }
        return nbPiece;
    }
    
    public static int evaluateBoard(int[][] board){
        int evaluation = 0;
        
        ArrayList<Integer> countNumberPiece = countNumberPiece(board);
        if (isWhitePlayer()){
            if(countNumberPiece.get(2) == 0) {
                return 1000;
            } else if(countNumberPiece.get(4) == 0) {
                return -1000;
            }
            for (int k=0;k<8;k++){
                //if the board contains white value players on the last row AND that there is no presence of 
                //black players on their first row -------> WIN
                if ((board[k][0] == 3 || board[k][0] == 4) && !(board[k][7] == 1 || board[k][7] == 2)){
                    return 1000;
                } else if(board[k][7] == 1 || board[k][7] == 2) {
                    return -1000;
                }
            }
            evaluation += countNumberPiece.get(3) * Constante.PONDE_POUSSER;
            evaluation += countNumberPiece.get(4) * Constante.PONDE_POUSSEUR;
        
            evaluation -= countNumberPiece.get(1) * Constante.PONDE_POUSSER * Constante.PONDDEF;
            evaluation -= countNumberPiece.get(2) * Constante.PONDE_POUSSEUR * Constante.PONDDEF;
       
            for(int i = 0; i < 8; i ++) {
                for(int j = 0; j < 8; j ++) {
                    if(j <= 3 && board[i][j] == 3) {
                        evaluation += Math.pow(2,4 - j);
                    } else if(j <= 3 && board[i][j] == 4) {
                        evaluation += Math.pow(3,4 - j);
                    } else if(j > 3 && board[i][j] == 1) {
                        evaluation -= Math.pow(2,j - 4) * Constante.PONDDEF;
                    } else if(j > 3 && board[i][j] == 2) {
                        evaluation -= Math.pow(3,j - 4) * Constante.PONDDEF;
                    }
                }
            }
        }else if (!isWhitePlayer()){
            if(countNumberPiece.get(4) == 0) {
                return 1000;
            } else if(countNumberPiece.get(2) == 0) {
                return -1000;
            }
            for (int k=0;k<8;k++){
                //if the board contains white value players on the last row AND that there is no presence of 
                //black players on their first row -------> WIN
                if (!(board[k][0] == 3 || board[k][0] == 4) && (board[k][7] == 1 || board[k][7] == 2)){
                    return 1000;
                } else if (board[k][0] == 3 || board[k][0] == 4){
                    return -1000;
                }
            }
            
            evaluation -= countNumberPiece.get(3) * Constante.PONDE_POUSSER  * Constante.PONDDEF;
            evaluation -= countNumberPiece.get(4) * Constante.PONDE_POUSSEUR  * Constante.PONDDEF;
        
            evaluation += countNumberPiece.get(1) * Constante.PONDE_POUSSER;
            evaluation += countNumberPiece.get(2) * Constante.PONDE_POUSSEUR;
       
            for(int i = 0; i < 8; i ++) {
                for(int j = 0; j < 8; j ++) {
                    if(j <= 3 && board[i][j] == 3) {
                        evaluation -= Math.pow(2,4 - j) * Constante.PONDDEF;
                    } else if(j <= 3 && board[i][j] == 4) {
                        evaluation -= Math.pow(3,4 - j) * Constante.PONDDEF;
                    } else if(j > 3 && board[i][j] == 1) {
                        evaluation += Math.pow(2,j - 4);
                    } else if(j > 3 && board[i][j] == 2) {
                        evaluation += Math.pow(3,j - 4);
                    }
                    
                }
            }
        }

        showBoard(board);
        System.out.println("Evaluation : " + evaluation);
        return evaluation;
    }
    /**
     * Static method that will be called to analyse a move
     * This method will be develop in a minMax and AlphaBeta
     * mindset. 
     */
    public static String evaluateBestMove(LinkedList<String> arrayMouvement,int [][] board){
        Arbre abr = new Arbre(arrayMouvement,board);

        return abr.calculerMinMaxAB();
    }
}
